package cate.game.videohall;

import cate.common.rpc.path.RpcCommonPath;
import cate.common.table.d.GDVideoHall;
import cate.common.util.GameResult;
import cate.common.util.TimeTool;
import cate.game.db.facade.KvLoader;
import cate.game.db.mongo.kv.KvMongo;
import cate.game.framework.ModuleMan;
import cate.game.play.part.BattleHero;
import cate.game.play.proce.play.PlayPO;
import cate.game.play.vo.ReplayUtils;
import cate.game.role.Role;
import cate.game.role.pvp.videohall.msg.*;
import cate.game.videohall.po.VideoGroupPO;
import cate.game.videohall.po.VideoHallSPO;
import cate.game.videohall.po.VideoPO;
import cate.game.videohall.routing.VideoRoutingMsg;
import cp.solution.manage.api.open.replay.ReplaySaveReq;
import cp.solution.manage.api.open.replay.ReplaySaveResp;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import org.apache.commons.lang3.StringUtils;

import java.util.Set;
import java.util.stream.Collectors;

@NoteClass(value = "录像馆管理")
public class VideoHallManager extends ModuleMan {

    public static final String MODULE_NAME = "video-hall";

    @NoteField(value = "录像馆状态")
    public VideoHallSPO status;

    @Override
    public void initDependent() throws Exception {
        status = new KvLoader<>(game, VideoHallSPO.class, KvMongo.KEY_VIDEO_HALL).getBySrvId();
        game.rpcRecv().onFireAndForgetTemplate(RpcCommonPath.VIDEO_CROSS_TO_GAME, VideoRoutingMsg.class,
                (h, input) -> addVideo(input.getGroup(), input.getPlayPO()));
    }

    public void save() {
        game.db.kv.save(status);
    }

    public void getVideoGroupVo(Role role, GDVideoHall.Group g) {
        VideoGroupPO data = getGroup(role, g);
        Set<String> collectUids = role.getPvp().videoHall.getGroup(GDVideoHall.Group.MY_COLLECT)
                .list.stream()
                .filter(e->e != null && e.replayProfile != null)
                .map(e -> e.replayProfile.replayUid).collect(Collectors.toSet());
        VideoGroupResp resp = new VideoGroupResp(data, collectUids);
        status.loadVideoData(resp.group);
        role.sendNow(resp);
    }

    private VideoGroupPO getGroup(Role role, GDVideoHall.Group group) {
        if (group == GDVideoHall.Group.MY_COLLECT) {
            return role.getPvp().videoHall.getGroup(GDVideoHall.Group.MY_COLLECT);
        }
        return status.getGroup(role, group);
    }

    public void addVideo(GDVideoHall.Group group, PlayPO playPO) {
        try{
            status.addVideo(game, group, playPO);
        } catch (Exception e) {
            log.error("添加录像馆失败拉，group={}, e=", group, e);
        }
    }

    public int admire(Role role, String replayUid) {
        return status.admireVideo(role, replayUid);
    }

    public GameResult<Void> playVideo(Role role, String replayUid) {
        GameResult<Void> r = new GameResult<>();
        // 历史记录
        int playedTimes = status.playVideo(replayUid);
        role.getHistory().action.playVideo();
        role.sendNow(new PlayVideoResp(playedTimes, replayUid));
        return r;
    }

    public GameResult<Void> shareVideo(Role role, String replayUid) {
        GameResult<Void> r = new GameResult<>();
        int shareTimes = status.shareVideo(replayUid);
        long replayUid2 = 0L;
        PlayPO playPO = game.facilities.getMongo().play.findById(replayUid).orElse(null);
        if (playPO != null) {
            try {
                ReplaySaveReq saveReq = ReplayUtils.toReplaySaveReq(playPO,
                        role.getGame().time.now() + TimeTool.TimeCons.DAY);
                EcResult<ReplaySaveResp> saveRes = game.facilities.getApi().open().saveReplay(saveReq);
                if (saveRes.ok()) {
                    replayUid2 = saveRes.data.getId();
                }
            } catch (Exception e) {

            }
        }
        role.sendNow(new ShareVideoResp(shareTimes, replayUid, replayUid2));
        return r;
    }

    public GameResult<Void> videoDetail(Role role, int group, String replayUid) {
        GameResult<Void> r = new GameResult<>();
        GDVideoHall.Group g = GDVideoHall.Group.getGroup(group);
        if (g == null) {
            return r.fail("错误的录像分组");
        }
        VideoPO video = status.getVideo(role, g, replayUid);
        if (video == null) {
            return r.fail("录像已过期");
        }
        role.sendNow(new VideoDetailResp(group, video));
        return r;
    }

    public GameResult<Void> videoHeroDetail(Role role, int group, String replayUid, byte team, byte pos) {
        GameResult<Void> r = new GameResult<>();
        GDVideoHall.Group g = GDVideoHall.Group.getGroup(group);
        if (g == null) {
            return r.fail("错误的录像分组");
        }
        VideoPO video = status.getVideo(role, g, replayUid);
        if (video == null) {
            return r.fail("录像已过期");
        }
        BattleHero hero = video.replayProfile.findHero(team, pos);
        if (hero == null) {
            return r.fail("英雄不存在");
        }
        role.sendNow(new VideoHeroDetailResp(group, video.replayProfile.replayUid, hero));
        return r;
    }

    public GameResult<Void> collect(Role role, String replayUid) {
        if (StringUtils.isBlank(replayUid)) {
            return new GameResult<Void>().fail("录像不存在");
        }
        return status.collect(role, replayUid);
    }

    public GameResult<Void> cancelCollect(Role role, String replayUid) {
        if (StringUtils.isBlank(replayUid)) {
            return new GameResult<Void>().fail("录像不存在");
        }
        return status.cancelCollect(role, replayUid);
    }

    @Override
    public void onDaySpan() {
        synchronized (this) {
            status.groups.forEach(VideoGroupPO::removeExpired);
        }
    }
}
